home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / utils / inttools / intview.asm < prev    next >
Assembly Source File  |  1995-04-20  |  10KB  |  350 lines

  1. ;
  2. ;  Program to print the segment, and offset info of an interrupt handler.
  3. ;  Version One,  Steve Kemp  '95
  4. ;
  5. ;   Operation, either
  6. ;
  7. ;   INTVIEW [/?]      - Print info
  8. ;   INTVIEW /A        - Print all interrupt handlers addresses
  9. ;   INTVIEW xx        - xx = Decimal int. number to print location of
  10. ;   INTVIEW xxh       - xx = Hexidecimal int. number to print location of.
  11. ;
  12. ;
  13. ;
  14. ;   e.g.  Find the location of the int 13h handler, either use:
  15. ;
  16. ;   INTVIEW 13h, or INTVIEW 19    (13h=19 decimal)
  17. ;
  18.  
  19. parser:
  20.         mov SI,80h
  21. parse_loop:
  22.         inc SI                    ; Get ready for next character
  23.         mov Dl,[SI]                ; Get character from command tail
  24.         cmp Dl,'/'                ; Switch??
  25.         jz found_slash            ; If so goto switch routine
  26.         cmp Dl,0Dh                ; End of tail??
  27.         jnz parse_loop            ; If not repeat
  28.  
  29.         cmp SI,81h                ; Still at start of tail??
  30.         jnz number_entered        ; If not continue
  31.         
  32.         mov DX,info_message        ; Else queue up error message
  33.         call print_string        ; Print it
  34.         jmp return2DOS            ; and return to DOS
  35.  
  36. number_entered:    
  37.         call calculate_number    ; Calculate number on command line
  38.                                 ; Store it in int_number
  39.  
  40.         mov AX,[int_number]        ; Get the number calculated
  41.         cmp AX,255                ; Is it bigger than 255??
  42.         jle not_too_big            ; If not continue
  43.  
  44.         mov DX,too_big            ; Queue up 'Too big message'
  45.         call print_string        ; Print it
  46.         jmp return2DOS            ; Stop
  47.  
  48. not_too_big:
  49.         call print_initial        ; Print the int number selected
  50.         call display_address    ; Now print the actual segment:offset
  51.         jmp return2DOS            ; Return to DOS
  52.  
  53. found_slash:
  54.         inc SI                    ; Point to next letter
  55.         mov Dl,[SI]                ; Get it into Dl
  56.         cmp Dl,'?'                ; ? ?? If so print info about program
  57.         jz info    
  58.         or Dl,32                ; Convert to ASCII lowercase
  59.         cmp Dl,'a'
  60.         jz do_all                ; /a ?? If so go setup printing all
  61.         push DX                    ; Otherwise invalid switch.  Save it
  62.         mov DX,invalid_switch    ; Print invalid switch message
  63.         call print_string        ; Here
  64.         pop DX                    ; Get back saved letter
  65.         add Dl,'A'-'a'            ; Print uppercase version of letter
  66.         mov Ah,02                ; Print a single character
  67.         int 21h                    ; Now!
  68. return2DOS:
  69.         mov Ah,4ch                ; Return to DOS
  70.         int 21h                    ; There!
  71.  
  72. info:
  73.         mov DX,info_message        ; Point to info. string
  74.         call print_string        ; Print the string
  75.         jmp return2DOS            ; finished!
  76.  
  77. ;
  78. ;  Pleasant routine to print out all the interrupts, one after the other
  79. ; by looping and increasing the int. number to display on each iteration
  80. ;
  81. do_all:
  82.         mov CX,00                ; Counter
  83. do_all_loop:
  84.         push CX                    ; Save counter on the stack
  85.         mov [int_number],CX        ; Adjust the number to print
  86.         call print_initial        ; print the initial message
  87.         call display_address    ; Now print the handlers address
  88.         call print_crlf            ; Print a CR, LF
  89.         pop CX
  90.         inc Cl
  91.         cmp Cl,00
  92.         jnz do_all_loop
  93.         jmp return2DOS
  94.  
  95. ;
  96. ; The following routine determines whether the input number is hex or
  97. ; decimal, and calculates it, storing the result into the buffer 'int_number'
  98. ;
  99. calculate_number:
  100.         mov SI,82h                    ; Number is first parameter on Command
  101.         mov DI,ascii_buffer            ; Put a copy of it into the temporary
  102.         movsw                        ; buffer
  103.         movsb
  104.  
  105.         dec SI                        ; Point to buffer+1
  106.         mov CX,2                    ; Three bytes long max
  107. hex_or_dec:
  108.         mov Dl,[si]                    ; Get a letter
  109.         or Dl,32
  110.         cmp dl,"h"                    ; Is it a hex number marker??
  111.         jz hex_number
  112.         inc SI
  113.         loop hex_or_dec                ; Repeat
  114.  
  115. decimal_number:
  116.         mov CX,0003
  117.         mov AX,0000
  118.         mov SI,ascii_buffer
  119. test_validity:
  120.         mov Dl,[SI]
  121.         cmp Dl,'0'-1
  122.         jle end_of_number
  123.         cmp Dl,'9'+1
  124.         jge end_of_number
  125.         inc AX
  126.         inc SI
  127.         loop test_validity
  128.  
  129. end_of_number:
  130.         mov SI,ascii_buffer        ; Reset pointer    
  131.         mov Dh,00h                ; Blank high byte of Dh
  132.         cmp AX,0001
  133.         jz one_byte
  134.         cmp AX,0002
  135.         jz two_byte
  136.         cmp AX,0003
  137.         jz three_byte
  138.         ret
  139.  
  140. one_byte:                        ; We have a one ASCII-digit number
  141.         mov Dl,[SI]                ; Get the digit
  142.         sub Dl,'0'                ; Convert it.
  143.         mov word ptr [int_number],DX    ; Dh=00 already
  144.         ret
  145.  
  146. two_byte:
  147.         mov Dl,[SI]                ; Get the most significant number
  148.         sub Dl,'0'                ; Convert it
  149.         mov Al,10                ; Multiply it by ten, high byte =00h
  150.         mul DX                    ; Result in AX
  151.         xor DX,DX                ; Set DX=0000
  152.         inc SI                    ; Point to next number
  153.         mov Dl,[SI]                ; Get it.
  154.         sub Dl,'0'                ; Canvert that
  155.         add DX,AX                ; Add it to total
  156.         mov word ptr [int_number],DX    ; Store it in the store
  157.         ret                        ; Return
  158.  
  159. three_byte:
  160.         mov Dl,[Si]                ; Get first letter
  161.         sub Dl,'0'                ; Convert it to 0-9
  162.         mov AX,100                ; We want to multiply it by 100
  163.         mul DX                    ; Do it. Returns the result in AX
  164.         mov BX,AX                ; Save it in BX
  165.         inc SI                    ; Point to next letter
  166.         call two_byte            ; Proceed as if it were only two digits
  167.         add DX,BX                ; Add the two digit total to the preserved
  168.         mov word ptr [int_number],DX    ; BX, and store it in the store
  169.         ret                        ; Return
  170.  
  171.  
  172. ;
  173. ;  Hex numbers handled here
  174. ;
  175. hex_number:
  176.         mov SI,ascii_buffer        ; Point to beginning of ASCII buffer
  177.         mov Dl,[SI]                ; Get a character
  178.         inc SI                    ; Move pointer up by one
  179.         mov Dh,[SI]                ; Get another character
  180.         or Dh,32                ; Conver secong character to lower case
  181.         cmp Dh,'h'                ; Is it a 'h'
  182.         jz one_digit_hex        ; If so number is one ASCII-byte long
  183.         
  184. two_digit_hex:                    ; Else it MUST be two ASCII-bytes long
  185.         cmp Dl,'9'
  186.         jle less_than_nine_1    ; Is it a number??
  187.         or Dl,32                ; If not its a letter, lowercase it becomes
  188.         sub dl,'a'-10-'0'        ; Adjust value
  189. less_than_nine_1:
  190.         sub Dl,'0'                ; Convert it to number 0-15
  191.         mov AX,16                ; Get ready to multiply by 16
  192.         mov Dh,00                
  193.         mul DX                    ; Do it! (Result in AX)
  194.         push AX                    ; Save result on stack
  195.         mov Dl,[SI]                ; Get next digit
  196.         call one_digit_hex        ; Treat it as a one digit number
  197.         pop AX                    ; Restore the value that we saved
  198.         add AX,DX                ; Add high+low results
  199.         mov [int_number],AX        ; Finally store the result in the bufffer
  200.         ret                        ; Finished (Phew!)
  201.  
  202. one_digit_hex:
  203.         cmp Dl,'9'                ; Is it a digit??
  204.         jle less_than_nine_2    ; If so goto digit routine
  205.         or dl,32                ; Convert letter to lower case
  206.         sub Dl,'a'-'9'-1        ; Adjust it
  207. less_than_nine_2:
  208.         sub Dl,'0'                ; Convert it to a number 0-15
  209.         mov Dh,00                ; Blank out high byte
  210.         mov [int_number],DX        ; Store in the buffer
  211.         ret                        ; Return
  212.  
  213. print_initial:
  214.         mov DX,initial_message    ; Queue up message
  215.         call print_string        ; Print it
  216.         mov AX,[int_number]        ; Get the interupt number
  217.         mov Ah,Al                ; Put it in Ah
  218.         call print_hex            ; Print out Ah
  219.         mov DX,final_message    ; Queue up message
  220.         call print_string        ; Print it
  221.         ret                        ; Return
  222.  
  223. ;
  224. ; This routine prints the contents of Ah as a two-byte hex number.
  225. ;
  226. print_hex:
  227.          mov al,ah
  228.          shr ah,1
  229.          shr ah,1
  230.          shr ah,1
  231.          shr ah,1
  232.          cmp ah,9
  233.          jbe next1
  234.          add ah,7
  235. next1:
  236.         add ah,'0'
  237.          and al,0fh
  238.         cmp al,9
  239.          jbe next2
  240.          add al,7
  241. next2:
  242.         add al,'0'
  243.         push cx
  244.         mov cl,ah
  245.         mov ch,al
  246.          mov Ah,02
  247.          mov Dl,cl
  248.          int 21h
  249.          mov Ah,02
  250.          mov Dl,ch
  251.          int 21h
  252.         pop cx
  253.         ret
  254.  
  255.  
  256. ;
  257. ; This routine actually prints the segment:offset info of the interrupt
  258. ; number stored in 'int_number'
  259. ;
  260. Display_address:
  261.         mov AX,0004                    ; Multiply int number by four
  262.         mov BX,[int_number]            ; Get int. number
  263.         mul BX                        ; Do the multiplication
  264.         mov SI,AX                    ; Set the pointer accordingly
  265.  
  266.         push DS                        ; Save the data segment
  267.         xor AX,AX                    ; AX=0000
  268.         push AX                        ; Store the zero value on the stack
  269.         pop DS                        ; Data segment=0000
  270.     
  271.         mov AX,[SI]                    ; Get the offset of the handler
  272.         inc SI                        ; increase pointer
  273.         inc SI                        ; increase pointer to point to the offset
  274.         mov BX,[SI]                    ; Get the offset
  275.         pop DS                        ; Restore data segment
  276.  
  277.         mov word ptr [offset_buffer],AX    ; Store the segment
  278.         mov word ptr [segment_buffer],BX    ; Store the offset
  279.     
  280.         push AX
  281.         mov CX,BX
  282.         pop BX                        ; Swap the registers around
  283.         mov AX,CX
  284.  
  285.         push BX                        ; Keep a copy of the offset on the stack
  286.         push AX                        ; And keep the segment
  287.         call print_hex                ; Print the high byte of the segment
  288.         pop AX
  289.         mov Ah,Al
  290.         call print_hex                ; Print the lowbyte of the segment
  291.  
  292.         mov Ah,02                    ; Print a single letter
  293.         mov Dl,':'                    ; A seporater
  294.         int 21h                        ; Now!
  295.  
  296.         pop BX                        ; Restore the offset
  297.         push BX                        ; Save it for later
  298.         mov Ah,Bh                    ; Print the highbyte
  299.         call print_hex
  300.         pop AX
  301.         mov Ah,Al
  302.         call print_hex                ; Print the low byte
  303.  
  304.         ret                            ; Return
  305.  
  306. print_crlf:
  307.         mov DX,lfcr                    ; Point to linefeed, CR
  308. print_string:
  309.         mov Ah,09h                    ; Get ready to output the string addressed
  310.         int 21h                        ; By DX. Do it.
  311.         ret                            ; Return
  312.  
  313. ; **************************************************************************
  314. ; * Output Strings and Data area *
  315. ; ********************************
  316.  
  317. invalid_switch:
  318.         db "Invalid switch - /","$"
  319. too_big:
  320.         db "Interupt number too big!","$"
  321. info_message:
  322.         db "INTVIEW Version One - Steven Kemp 1995",0ah,0dh
  323.         db 0ah,0dh
  324.         db "     Usage:     INTVIEW [/?]    - Show this information",0ah,0dh
  325.         db 0ah,0dh
  326.         db "                INTVIEW xxx[h]    - Show the segment:offset information",0ah,0dh
  327.         db "                                  of int. number xxx (Assumes decimal)",0ah,0dh
  328.         db "                                - Can overide by the 'h' suffix.",0ah,0dh
  329.         db 0ah,0dh
  330.         db "                INTVIEW /A      - Show the info on _all_ the interrupts",0ah,0dh
  331.         db "$"
  332. initial_message:
  333.         db "Interrupt number ","$"
  334. final_message:
  335.         db "h has its handler at ","$"
  336. lfcr:
  337.         db 0A,0Dh,"$"
  338.  
  339. ascii_buffer:
  340.         db 00,00,00
  341.  
  342. int_number:
  343.         dw 0000h
  344.  
  345. offset_buffer:
  346.         dw 0000h
  347.  
  348. segment_buffer:
  349.         dw 0000h
  350.